home *** CD-ROM | disk | FTP | other *** search
/ Windows Game Programming for Dummies (2nd Edition) / WinGamProgFD.iso / pc / DirectX SDK / DXSDK / samples / Multimedia / DirectPlay / Maze / MazeCommon / MazeServer.h < prev    next >
Encoding:
C/C++ Source or Header  |  2001-10-31  |  10.7 KB  |  276 lines

  1. //----------------------------------------------------------------------------
  2. // File: mazeserver.h
  3. //
  4. // Desc: see main.cpp
  5. //
  6. // Copyright (c) 1999-2001 Microsoft Corp. All rights reserved.
  7. //-----------------------------------------------------------------------------
  8. #ifndef _MAZESERVER_H
  9. #define _MAZESERVER_H
  10.  
  11.  
  12.  
  13.  
  14.  
  15. //-----------------------------------------------------------------------------
  16. // Name: 
  17. // Desc: 
  18. //-----------------------------------------------------------------------------
  19. #include "NetAbstract.h"
  20. #include "SyncObjects.h"
  21. #include "Maze.h"
  22. #include "Random.h"
  23. #include "Packets.h"
  24. #include "Trig.h"
  25.  
  26. class   CMaze;
  27. struct  ClientPosPacket;
  28.  
  29. #define SERVER_MAX_WIDTH    128
  30. #define SERVER_MAX_HEIGHT   128
  31. #define DEFAULT_MAZE_WIDTH  16
  32. #define DEFAULT_MAZE_HEIGHT 16
  33. #define DEFAULT_SEED        314159
  34. #define LOCK_GRID_SIZE      16
  35.  
  36.  
  37.  
  38.  
  39. //-----------------------------------------------------------------------------
  40. // Name: 
  41. // Desc: 
  42. //-----------------------------------------------------------------------------
  43. struct PlayerData
  44. {
  45.     DWORD           dwID;                   // Client ID
  46.     DWORD           NetID;                  // NetID for owning player (0 if none)
  47.     DWORD           dwVersion;              // Version of the owning player
  48.     BOOL            bAllow;                 // If FALSE, then we should drop this player
  49.  
  50.     // Links for the various lists
  51.     PlayerData*     pNext;                  // Free/active PlayerData list (double link)
  52.     PlayerData*     pPrevious;
  53.     PlayerData*     pNextInCell;            // Cell list (single link)
  54.     PlayerData*     pNextInIDHashBucket;    // ID hash bucket (single link)
  55.  
  56.     FLOAT           fLastDisplayTime;
  57.     FLOAT           fLastCITime;
  58.     BOOL            bActive;
  59.  
  60.     float           fPosX;                  // Floating point position
  61.     float           fPosY;
  62.     WORD            wCellX;                 // Coordinates of the cell this player is in
  63.     WORD            wCellY;                 // or (0xffff,0xffff) for off-map
  64.     ANGLE           aCameraYaw;
  65.     DWORD           dwNumNearbyPlayers;     // Number of nearby players
  66.  
  67.     DWORD           pad[4];
  68. };
  69.  
  70.  
  71.  
  72.  
  73. //-----------------------------------------------------------------------------
  74. // Name: 
  75. // Desc: 
  76. //-----------------------------------------------------------------------------
  77. struct ServerCell
  78. {
  79.     PlayerData* pFirstPlayerData;
  80. };
  81.  
  82.  
  83.  
  84.  
  85. //-----------------------------------------------------------------------------
  86. // Name: 
  87. // Desc: 
  88. //-----------------------------------------------------------------------------
  89. class CMazeServer : public INetServer
  90. {
  91. public:
  92.     CMazeServer();
  93.  
  94.     // From INetServer
  95.     void    OnAddConnection( DWORD dwID );
  96.     HRESULT OnPacket( DWORD from, void* pData, DWORD dwSize );
  97.     void    OnRemoveConnection( DWORD dwID );
  98.     void    OnSessionLost( DWORD dwReason );
  99.  
  100.     // Hook up to the network service
  101.     void    SetOutboundServer( IOutboundServer* poutnet ) { m_pNet = poutnet; };
  102.  
  103.     // Initialisation - need to hook up a maze object
  104.     HRESULT Init( BOOL bLocalLoopback, const CMaze* pmaze );
  105.     void    Shutdown();
  106.  
  107.     // Chance of server sending packets via reliable transport
  108.     void    SetServerReliableRate( DWORD percent ) { m_dwServerReliableRate = percent; };
  109.     DWORD   GetServerReliableRate() const { return m_dwServerReliableRate; };
  110.  
  111.     // Timeout of server's packets
  112.     void    SetServerTimeout( DWORD timeout ) { m_dwServerTimeout = timeout; };
  113.     DWORD   GetServerTimeout() const { return m_dwServerTimeout; };
  114.  
  115.     // Change of client sending packets via reliable transport. Setting this causes the server
  116.     // to propagate this setting to all currently connected clients
  117.     void    SetClientReliableRate( DWORD percent );
  118.     DWORD   GetClientReliableRate() const { return DWORD(m_ClientNetConfig.ubReliableRate); };
  119.  
  120.     // Change client update rate. Setting this causes the server to propagate this setting to all
  121.     // currently connected clients
  122.     void    SetClientUpdateRate( DWORD rate );
  123.     DWORD   GetClientUpdateRate() const { return DWORD(m_ClientNetConfig.wUpdateRate); };
  124.  
  125.     // Change client timeout. Setting this causes the server to propagate this setting to all
  126.     // currently connected clients
  127.     void    SetClientTimeout( DWORD timeout );
  128.     DWORD   GetClientTimeout() const { return DWORD(m_ClientNetConfig.wTimeout); };
  129.  
  130.     // Change Client position pack size. Setting this causes the server to propagate this setting to all
  131.     // currently connected clients
  132.     void    SetClientPackSize( DWORD size );
  133.     DWORD   GetClientPackSize() const { return DWORD(m_ClientNetConfig.wClientPackSizeArray[m_ClientNetConfig.ubClientPackIndex]); };
  134.  
  135.     // Change Server position pack size.
  136.     void    SetServerPackSize( DWORD size );
  137.     DWORD   GetServerPackSize() const { return DWORD(m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex]); };
  138.     
  139.     // How long the user wants to hold the Server's Dplay Threads
  140.     void    SetServerThreadWait( DWORD threadwait ) { m_dwServerThreadWait = threadwait; };
  141.     DWORD   GetServerThreadWait() const { return m_dwServerThreadWait; };
  142.  
  143.     // How long the user wants to hold the Server's Dplay Threads
  144.     void    SetClientThreadWait( DWORD threadwait );
  145.     DWORD   GetClientThreadWait() const { return DWORD(m_ClientNetConfig.dwThreadWait); };
  146.     
  147.     
  148.     // Various commands
  149.     void    DisplayConnectionInfo( DWORD dwID );
  150.     void    DisplayNextConnectionInfo();
  151.     void    PrintStats();
  152.  
  153.     void    SetLogLevel( DWORD dwLogLevel ) { m_dwLogLevel = dwLogLevel; }
  154.     DWORD   GetLogLevel() { return m_dwLogLevel; }
  155.  
  156.     DWORD   GetNumPlayers() { return m_dwPlayerCount; }
  157.  
  158. protected:
  159.     BOOL                m_bLocalLoopback;
  160.     IOutboundServer*    m_pNet;
  161.     const CMaze*        m_pMaze;
  162.     DWORD               m_dwLogLevel;
  163.     DWORD               m_dwWidth;
  164.     DWORD               m_dwHeight;
  165.     CCriticalSection    m_AddRemoveLock;
  166.  
  167.     // A fixed sized grid of locks which we lay over the maze to control access to it
  168.     // We demand that the maze dimensions are a power-of-2 times the dimensions of this
  169.     // grid, and pre-store that power to allow fast translation
  170.     CLockArray<LOCK_GRID_SIZE,LOCK_GRID_SIZE>   m_LockGrid;
  171.     DWORD               m_dwMazeXShift;
  172.     DWORD               m_dwMazeYShift;
  173.     void                LockCell( DWORD x , DWORD y );
  174.     void                UnlockCell( DWORD x , DWORD y );
  175.     void                LockRange( DWORD x1 , DWORD y1 , DWORD x2 , DWORD y2 );
  176.     void                UnlockRange( DWORD x1 , DWORD y1 , DWORD x2 , DWORD y2 );
  177.     void                LockCellPair( DWORD x1 , DWORD y1 , DWORD x2 , DWORD y2 );
  178.     void                UnlockCellPair( DWORD x1 , DWORD y1 , DWORD x2 , DWORD y2 );
  179.     CCriticalSection    m_OffMapLock;
  180.  
  181.     // The PlayerData lists
  182.     PlayerData          m_PlayerDatas[MAX_PLAYER_OBJECTS];
  183.     PlayerData*         m_pFirstActivePlayerData;
  184.     PlayerData*         m_pFirstFreePlayerData;
  185.     DWORD               m_dwActivePlayerDataCount;
  186.     DWORD               m_dwPlayerDataUniqueValue;
  187.     CCriticalSection    m_PlayerDataListLock;
  188.  
  189.     // The player object locks
  190.     enum { NUM_PLAYER_OBJECT_LOCKS = 16 };
  191.     CCriticalSection    m_PlayerDataLocks[NUM_PLAYER_OBJECT_LOCKS];
  192.     void                LockPlayerData( PlayerData* pPlayerData ) { m_PlayerDataLocks[((pPlayerData-m_PlayerDatas) & (NUM_PLAYER_OBJECT_LOCKS-1))].Enter(); };
  193.     void                UnlockPlayerData( PlayerData* pPlayerData ) { m_PlayerDataLocks[((pPlayerData-m_PlayerDatas) & (NUM_PLAYER_OBJECT_LOCKS-1))].Leave(); };
  194.  
  195.     PlayerData*        CreatePlayerData();
  196.     void                DestroyPlayerData( PlayerData* pPlayerData );
  197.  
  198.     // The cell array and the "off-map" cell.
  199.     ServerCell          m_OffMapCell;
  200.     ServerCell          m_Cells[SERVER_MAX_WIDTH][SERVER_MAX_HEIGHT];
  201.  
  202.     // Remove playerdata from its cell
  203.     void    RemovePlayerDataFromCell( PlayerData* pPlayerData );
  204.  
  205.     // Unsafe versions of add/remove. Must have playerdata and cell locked when you call this
  206.     void    UnsafeRemovePlayerDataFromCell( PlayerData* pPlayerData );
  207.     void    UnsafeAddPlayerDataToCell( PlayerData* pPlayerData );
  208.  
  209.     ServerCell* GetCell( PlayerData* pPlayerData )
  210.     {
  211.         if ( pPlayerData->wCellX == 0xffff )
  212.             return &m_OffMapCell;
  213.         else
  214.             return &m_Cells[pPlayerData->wCellY][pPlayerData->wCellX];
  215.     };
  216.  
  217.     void    HandleClientPosPacket( DWORD dwFrom, ClientPosPacket* pPacket );
  218.     void    HandleClientVersionPacket( DWORD dwFrom, ClientVersionPacket* pClientVersionPack );
  219.     void    HandleUnknownPacket( DWORD dwFrom, ClientPacket* pClientPack, DWORD size );
  220.  
  221.     BOOL    IsValidPackSize( DWORD wSize );
  222.     BOOL    IsClientVersionSupported( DWORD dwClientVersion );
  223.  
  224.     DWORD   m_dwPlayerCount;
  225.     
  226.     CCriticalSection    m_csThreadCountLock;    
  227.     WORD   m_wActiveThreadCount;
  228.     WORD   m_wMaxThreadCount;
  229.     FLOAT  m_fAvgThreadCount;
  230.     FLOAT  m_fAvgThreadTime;
  231.     FLOAT  m_fMaxThreadTime;
  232.  
  233.     DWORD  m_dwPeakPlayerCount;
  234.  
  235.     // Hashing DPIDs to PlayerData pointers
  236.     void                SetPlayerDataForID( DWORD dwID, PlayerData* pPlayerData );
  237.     PlayerData*        GetPlayerDataForID( DWORD dwID );
  238.     void                RemovePlayerDataID( PlayerData* pPlayerData );
  239.     DWORD               IDHash( DWORD dwID );
  240.     enum { NUM_ID_HASH_BUCKETS = 1024 };
  241.     enum { NUM_ID_HASH_BUCKET_LOCKS = 16 };
  242.     PlayerData*        m_pstIDHashBucket[NUM_ID_HASH_BUCKETS];
  243.     CCriticalSection    m_IDHashBucketLocks[NUM_ID_HASH_BUCKET_LOCKS];
  244.  
  245.     // Random number generator
  246.     CRandom     m_Rand;
  247.  
  248.     // Send packet wrapper
  249.     HRESULT SendPacket( DWORD dwTo, void* pData, DWORD dwSize, BOOL bReliable, DWORD dwTimeout );
  250.     void SendConfigPacketToAll( ServerConfigPacket* pPacket );
  251.  
  252.     // Network configuration parameters
  253.     DWORD               m_dwServerReliableRate;
  254.     DWORD               m_dwServerTimeout;
  255.     DWORD               m_dwServerThreadWait;
  256.  
  257.     ClientNetConfig     m_ClientNetConfig;
  258.     CCriticalSection    m_ClientNetConfigLock;
  259. };
  260.  
  261.  
  262.  
  263.  
  264. //-----------------------------------------------------------------------------
  265. // Name: 
  266. // Desc: This function is called by the server to output informational text.
  267. //       In the client it should probably just be a dummy function, in the server 
  268. //       it should probably just spew out to the console
  269. //-----------------------------------------------------------------------------
  270. enum ServerBufferType { SLINE_PROMPT, SLINE_INPUT, SLINE_LOG, SLINE_CMD };
  271. void ConsolePrintf( ServerBufferType enumLineType, const TCHAR* fmt , ... );
  272.  
  273.  
  274.  
  275. #endif
  276.